{# The scheduler clock (the landing page's, on live data). Counts and state are part of it: the hub says whether it is running, the legend closes with a one-line summary. Geometry comes from ``ui_scheduler.clock``. Each timed job is a slot rotated to its angle (``--angle``), holding its dot and its run's arc, so picking a job and moving it (static/js/clock.js) only turns the slot. The hand is a 24-hour CSS rotation started at the current time and always shows now. Moves are previews: nothing is saved. #} {# A job in the hub: its name, its time (with where it moved from, when ``moved`` says so), and a hint line from the call block. ``job`` is the Alpine expression naming the job (``selected``, ``hovered``). #} {% macro hub_job(job, moved="false") %}
{{ caller() }}
{% endmacro %} {% set meta = component.metadata or {} %} {# "running_persistent" -> "running": the store is already on the hub. #} {% set state = (meta.get("scheduler_state") or "unknown").split("_")[0] %}
{% for dot in clock.band.dots %} {% endfor %} {% for tick in clock.ticks %} {% endfor %} {% for label in clock.labels %} {% endfor %} {% for job in clock.cron %}
{% if job.arc %} {% endif %}
{% endfor %}
{% call hub_job("selected", "isMoved()") %}{{ clock.timezone }} · drag or use arrow keys{% endcall %}
Preview only, not saved
{% call hub_job("hovered") %}click to select, then drag{% endcall %}
APScheduler
{{ state }} · {{ store }} · {{ clock.timezone }}
{% for job in clock.cron %} {% else %}

No timed jobs.

{% endfor %} {% if clock.interval %}
{% for job in clock.interval %}
{{ job.every|lower }} · {{ job.name }}
{% endfor %}
{% endif %} {% set paused = meta.get("paused_tasks", 0) %}

{{ meta.get("total_tasks", 0) }} jobs · {{ meta.get("active_tasks", 0) }} active · {{ paused }} paused {%- if component.response_time_ms is not none %} · checked in {{ "%.0f"|format(component.response_time_ms) }} ms{% endif %}